package com.campus.secondhand.service.impl;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campus.secondhand.common.Result;
import com.campus.secondhand.entity.Product;
import com.campus.secondhand.entity.School;
import com.campus.secondhand.entity.User;
import com.campus.secondhand.mapper.ProductMapper;
import com.campus.secondhand.mapper.SchoolMapper;
import com.campus.secondhand.mapper.UserMapper;
import com.campus.secondhand.model.vo.ProductListVO;
import com.campus.secondhand.model.vo.SchoolUserStatusVO;
import com.campus.secondhand.service.ProductService;
import com.campus.secondhand.service.SchoolService;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 学校信息服务实现类
 */
@Service
@Slf4j
public class SchoolServiceImpl extends ServiceImpl<SchoolMapper, School> implements SchoolService {

    private final ProductMapper productMapper;
    private final ProductService productService;
    private final UserMapper userMapper;
    private final RedisTemplate<String, Object> redisTemplate;

    // Redis缓存键常量
    private static final String CACHE_SCHOOL_PREFIX = "school:";
    private static final String CACHE_ALL_SCHOOLS = "school:all";
    private static final String CACHE_SCHOOL_SEARCH = "school:search:";
    private static final String CACHE_SCHOOL_USER_STATUS = "school:user:status:";
    private static final long CACHE_EXPIRATION = 24; // 缓存过期时间，单位小时

    public SchoolServiceImpl(
            ProductMapper productMapper,
            @Lazy ProductService productService,
            UserMapper userMapper,
            RedisTemplate<String, Object> redisTemplate) {
        this.productMapper = productMapper;
        this.productService = productService;
        this.userMapper = userMapper;
        this.redisTemplate = redisTemplate;
    }

    @Override
    public Result<List<School>> getAllSchools() {
        // 尝试从缓存获取
        Object cachedSchools = redisTemplate.opsForValue().get(CACHE_ALL_SCHOOLS);
        if (cachedSchools != null) {
            return Result.success((List<School>) cachedSchools, "获取成功(缓存)");
        }

        // 缓存未命中，从数据库获取
        List<School> schools = this.list();

        // 写入缓存
        redisTemplate.opsForValue().set(CACHE_ALL_SCHOOLS, schools, CACHE_EXPIRATION, TimeUnit.HOURS);

        return Result.success(schools, "获取成功");
    }

    @Override
    public Result<School> getSchoolById(Long id) {
        // 尝试从缓存获取
        String cacheKey = CACHE_SCHOOL_PREFIX + id;
        Object cachedSchool = redisTemplate.opsForValue().get(cacheKey);
        if (cachedSchool != null) {
            return Result.success((School) cachedSchool, "获取成功(缓存)");
        }

        // 缓存未命中，从数据库获取
        School school = this.getById(id);
        if (school == null) {
            return Result.error(404, "学校不存在");
        }

        // 写入缓存
        redisTemplate.opsForValue().set(cacheKey, school, CACHE_EXPIRATION, TimeUnit.HOURS);

        return Result.success(school, "获取成功");
    }

    @Override
    public Result<List<School>> searchSchoolsByName(String name) {
        // 尝试从缓存获取
        String cacheKey = CACHE_SCHOOL_SEARCH + name;
        Object cachedSchools = redisTemplate.opsForValue().get(cacheKey);
        if (cachedSchools != null) {
            return Result.success((List<School>) cachedSchools, "搜索成功(缓存)");
        }

        // 缓存未命中，从数据库获取
        LambdaQueryWrapper<School> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(School::getName, name);
        List<School> schools = this.list(queryWrapper);

        // 写入缓存，搜索结果缓存时间短一些，设为1小时
        redisTemplate.opsForValue().set(cacheKey, schools, 1, TimeUnit.HOURS);

        return Result.success(schools, "搜索成功");
    }

    @Override
    public Result<SchoolUserStatusVO> getUserSchoolStatus(Long id, Long userId) {
        // 检查学校是否存在
        School school = this.getById(id);
        if (school == null) {
            return Result.error(404, "学校不存在");
        }

        // 如果未提供用户ID（未登录或匿名访问）
        if (userId == null) {
            SchoolUserStatusVO vo = SchoolUserStatusVO.builder()
                    .isJoined(false)
                    .isFavorite(false)
                    .build();
            return Result.success(vo, "获取成功");
        }

        // 尝试从缓存获取
        String cacheKey = CACHE_SCHOOL_USER_STATUS + id + ":" + userId;
        Object cachedStatus = redisTemplate.opsForValue().get(cacheKey);
        if (cachedStatus != null) {
            return Result.success((SchoolUserStatusVO) cachedStatus, "获取成功(缓存)");
        }

        // 获取用户信息
        User user = userMapper.selectById(userId);
        if (user == null) {
            return Result.error(404, "用户不存在");
        }

        // 获取用户是否为该学校的成员（根据用户表中的schoolId字段）
        boolean isJoined = user.getSchoolId() != null && user.getSchoolId().equals(id);

        // 构建返回对象
        // 注意：由于当前系统没有学校收藏功能的实体类，默认设置为false
        // 如果后续需要添加这个功能，需要创建相应的实体类和关系表
        SchoolUserStatusVO vo = SchoolUserStatusVO.builder()
                .isJoined(isJoined)
                .isFavorite(false) // 暂无收藏学校功能
                .build();

        // 写入缓存，用户状态缓存时间较短，设为1小时
        redisTemplate.opsForValue().set(cacheKey, vo, 1, TimeUnit.HOURS);

        return Result.success(vo, "获取成功");
    }

    @SuppressWarnings("unchecked")
    @Override
    public Result<Page<ProductListVO>> getSchoolProducts(Long id, Integer page, Integer size) {
        // 检查学校是否存在
        School school = this.getById(id);
        if (school == null) {
            return Result.error(404, "学校不存在");
        }

        // 使用现有的ProductService来获取商品列表
        // 注意我们将学校ID作为固定参数传入
        org.springframework.data.domain.Pageable pageable = PageRequest.of(page - 1, size);

        // 由于返回类型不同，需要进行类型适配
        Result<?> result = productService.getProductList(
                null, // 分类ID（不筛选）
                id, // 学校ID
                null, // 关键词
                null, // 最低价格（不筛选）
                null, // 最高价格（不筛选）
                "createdAt", // 默认按创建时间排序
                "desc", // 默认降序
                null, // 经度
                null, // 纬度
                pageable, // 分页参数
                null);

        // 返回结果适配
        if (result.getCode() != 200) {
            return Result.error(result.getCode(), result.getMessage());
        }

        return (Result<Page<ProductListVO>>) result;
    }

    /**
     * 清除学校缓存
     * 当学校数据发生变更时调用此方法
     */
    public void clearSchoolCache() {
        log.info("清除学校缓存");
        redisTemplate.delete(CACHE_ALL_SCHOOLS);
        // 可以使用pattern匹配删除所有学校相关缓存
        // Set<String> keys = redisTemplate.keys(CACHE_SCHOOL_PREFIX + "*");
        // if (keys != null && !keys.isEmpty()) {
        // redisTemplate.delete(keys);
        // }
    }

    /**
     * 清除指定学校的缓存
     */
    public void clearSchoolCache(Long schoolId) {
        log.info("清除学校缓存: {}", schoolId);
        String cacheKey = CACHE_SCHOOL_PREFIX + schoolId;
        redisTemplate.delete(cacheKey);
    }
}